# coding=utf-8
import datetime

from common.order.model import Order
from common.order_withdraw.model import OrderWithdraw
from common.mch.model import MchAccount
from common.range.model import Range, RangeCardsAssign
from common.utils.db import upsert, parse_query_dct, generate_filter, get_orderby
from common.utils.decorator import sql_wrapper
from common.utils.tz import (
    utc_to_local_str
)

DEFAULT_SIZE = 20


@sql_wrapper
def list_range(query_dict):
    query_dct = parse_query_dct(query_dict, Range)
    query = Range.query.filter(generate_filter(query_dct, Range))
    # total_count = get_count(query)
    orderby = get_orderby(query_dct.get('$orderby'), Range)
    if orderby is not None:
        query = query.order_by(orderby)

    return query.all()


@sql_wrapper
def get_range_dict(items, param, card=None):
    limit = param.get("$size", DEFAULT_SIZE)
    page = param.get("$page", 1)

    assign = RangeCardsAssign.query.all()
    range_assign = []
    for a in assign:
        range_assign.append(a.as_dict())

    result = []

    for r in items:
        data = r.as_dict()
        data['range_status'] = "Active" if r.status == 1 else "Inactive"
        data['range_type'] = "Collection" if r.type == 0 else "Payment"
        data['range_from_to'] = r.range_from + "-" + r.range_to
        data['updated_by'] = r.updated_by if r.updated_by is None else "Null"
        assign_data = filter(lambda x: x['id'] == r.assigned_id, range_assign)
        data['cards'] = assign_data[0]['cards'] if r.assigned_id and assign_data else ''
        data['companies'] = assign_data[0]['companies'] if r.assigned_id and assign_data else ''
        data['list_card'] = [c.upper() for c in data['cards'].split(',')]
        data['list_company'] = [c.upper() for c in data['companies'].split(',')]
        data['updated_at'] = utc_to_local_str(data['updated_at']) if data['updated_at'] else ''
        data['x'] = {'f': "l", "h": "o"}

        result.append(data)

    if card is not None:
        result = filter(lambda r: card in r['list_card'], result)

    result_list = []

    if result:
        result_list = [result[i:i + limit] for i in range(0, len(result), limit)]
        page = (page - 1)
        result_list = result_list[page]

    return result_list, result


@sql_wrapper
def insert_range(info, id=None):
    return upsert(Range, info, id)


@sql_wrapper
def update_range(info, id=None):
    return upsert(Range, info, int(id))


@sql_wrapper
def update_range_status(info, id=None):
    return upsert(Range, info, int(id))


@sql_wrapper
def assign_cards_to_range(info):
    result = ""
    assign_range = ""
    list_assign_range = {}
    existing_range = Range.query.filter(Range.id == info["id"]).first().as_dict()

    if not existing_range["assigned_id"] is None:
        list_assign_range["cards"] = info["cards"]
        list_assign_range["companies"] = info["companies"]
        list_assign_range["updated_by"] = info["updated_by"]

        assign_range = upsert(RangeCardsAssign, list_assign_range, existing_range["assigned_id"]).as_dict()
    else:
        list_assign_range["cards"] = info["cards"]
        list_assign_range["companies"] = info["companies"]
        list_assign_range["updated_by"] = info["updated_by"]
        list_assign_range["created_by"] = info["updated_by"]

        # __list_assign_range(list_assign_range, info)
        assign_range = upsert(RangeCardsAssign, list_assign_range).as_dict()

    list_range = {}
    list_range["assigned_id"] = assign_range["id"]
    list_range["updated_by"] = assign_range["updated_by"]
    list_range["updated_at"] = assign_range['updated_at']
    # datetime.datetime.utcnow()

    result = upsert(Range, list_range, info["id"]).as_dict()

    return result


def __list_assign_range(list_assign_range, info):
    list_assign_range["cards"] = info["cards"]
    list_assign_range["companies"] = info["companies"]
    list_assign_range["updated_by"] = info["updated_by"]
    return list_assign_range


@sql_wrapper
def get_range_only():
    range = Range.query.all()
    result = []
    for r in range:
        data = {}
        data["key"] = r.id
        data["value"] = r.range_code
        result.append(data)
    return result


@sql_wrapper
def list_order_deposit(card=None):
    order = Order.query.filter(Order.bankcard_name == card)

    result = []
    if order:
        for o in order:
            data = {}
            data["id"] = o.id
            data["cards"] = o.bankcard_name
            result.append(data)
    return result


@sql_wrapper
def list_order_withdraw(card=None):
    order = OrderWithdraw.query.filter(OrderWithdraw.source_card_code == card)

    result = []
    if order:
        for o in order:
            data = {}
            data["id"] = o.id
            data["cards"] = o.source_card_code
            result.append(data)
            
    return result


def get_range_for_orders():
    items = Range.query.all()
    assign = RangeCardsAssign.query.all()
    range_assign = []
    for a in assign:
        range_assign.append(a.as_dict())

    result = []
    cards = ""
    companies = ""
    for r in items:
        data = r.as_dict()
        data['range_status'] = "Active" if r.status == 1 else "Inactive"
        data['range_type'] = "Collection" if r.type == 0 else "Payment"
        data['range_from_to'] = r.range_from + "-" + r.range_to
        data['updated_by'] = r.updated_by if r.updated_by is None else "Null"
        assign_data = filter(lambda x: x['id'] == r.assigned_id, range_assign)
        data['cards'] = assign_data[0]['cards'] if r.assigned_id and assign_data else ''
        data['companies'] = assign_data[0]['companies'] if r.assigned_id and assign_data else ''
        data['list_card'] = [c.upper() for c in data['cards'].split(',')]
        data['list_company'] = [c.upper() for c in data['companies'].split(',')]
        result.append(data)

    return result
